#ifndef  __DOXON_H__
#define  __DOXON_H__

#include  "idle.h"

#include  "event.h"

/** 
 * @brief Onemogucava prekide(eng. Interrupts)
 *
 * pushf, i popf se koriste da bi se odrzala konziztentnost uprkos pozivima
 * funkcija
 */
#define lock()   asm{ pushf; cli;}
/** 
 * @brief Omogucava prekide(eng. Interrupts)
 */
#define unlock() asm{ popf; }

typedef void (interrupt *InterruptRoutine)();

class Doxon {
    public:
        /** 
         * @brief Inicijalizuje sistem tako sto menja podrazumevanu rutinu za
         * obradu timer prekida i stvara sistemske niti.
         */
        static void init();
        /** 
         * @brief Vraca podrazumevanu prekidnu rutinu za timer a pre toga vrsi
         * proveru da li su gotove sve korisnicke niti.
         */
        static void halt();
        /** 
         * @brief Vrsi eksplicitnu promenu konteksta
         */
        static void dispatch();
    private:
        friend class Thread;
        friend class PCB;

        friend class Semaphore;
        friend class Event;

        /** 
         * @brief Glavna nit sistema, ona koja je startovala init() funkciju.
         */
        static          Thread* starting;

        /** 
         * @brief Ova nit se izvrsava samo onda kad nema niceg drugog za
         * izvrsavanje.
         */
        static          Idle*    idle;

        /** 
         * @brief Nit koja se trenutno izvrsava na procesoru
         */
        static volatile PCB*     running;

        /** 
         * @brief Ima vrednost "true" ako je timer int pozvan eksplicitno u
         * suprotnom je "false".
         */
        static volatile char dispatched;

        /** 
         * @brief Zamenjuje interrupt handler 
         * 
         * @param int_num 
         * Broj interrupt-a ciju rutinu zelimo da menjamo.
         * @param newRoutine 
         * Adresa funkcije koja ce da opsluzuje dati interrupt.
         * 
         * @return 
         * Adresa stare interrupt funkcije.
         */
        static InterruptRoutine  replace_int(IVTNo int_num,
                                             InterruptRoutine newRoutine); 

        /** 
         * @brief Adresa DOS rutine za opsluzivanje timmer interrupt-a
         */
        static void     interrupt (*old_routine) ();

        /** 
         * @brief Rutina koja ce biti pozivana umesto
         * timer-a,...
         */
        static void     interrupt timer_int();
        /** 
         * @brief Funkcija koja obezbedjuje poziv run() metode iz Thread klase
         * i ciscenje reda za cekanje posle izvrsenja te klase.
         */
        static void     wrapper();
};


#endif  /*__DOXON_H__*/
